/**
 * This class provides general methods for reading and writing JSON strings
 * for more information on the JSON format please see json.org
 *
 * DISCLAIMER: This is an *incomplete* implementation of JSON.
 * 
 * This was written by Dan King, while attending Northeastern University's 
 * College of Computer Science and is released into the public domain.
 **/

import java.util.ArrayList;
import java.text.*;
class JSON {

  /**
   * Reads a JSON string representing an array and returns an array
   * of Java strings that contain the data listed in the json string
   **/
  public static String[] decodeJSONArray(String jsonstring) {
    int index = 0;
    ArrayList<String> array = new ArrayList<String>();
    String curElement = "";

    if(jsonstring.charAt(index) != '[') {
      throw new RuntimeException(JSON.malformedErrorString("JSON Array",
							   jsonstring));
    }
    while(true) {
      index++;
      if (index >= jsonstring.length()) {
	// end of string
	throw new RuntimeException(JSON.malformedErrorString("JSON Array",
							     jsonstring));
      } else if(jsonstring.charAt(index) == ',') {
	// end of element
	array.add(curElement);
	curElement = "";
      } else if(jsonstring.charAt(index) == ']') {
	// end of array
	array.add(curElement);
	curElement = "";
	String dummy[] = new String[0];
	return array.toArray(dummy);
      } else {
	// reading element
	curElement += jsonstring.charAt(index);
      }
    }

  }

  /**
   * Returns an even lengthed array where all the even indices
   * are value names and the odd indices are values
   **/
  public static String[] decodeJSONObject(String jsonstring) {
    CharacterIterator it = new StringCharacterIterator(jsonstring);
    ArrayList<String> array = new ArrayList<String>();
    String curElement = "";
    boolean readingName = true;
    
    if(it.current() != '{') {
      throw new RuntimeException(JSON.malformedErrorString("JSON Object-BRACE",
							   jsonstring));
    }

    it.next();

    while(true) {
      if(it.current() == StringCharacterIterator.DONE) {
	// end of string
	throw new RuntimeException(JSON.malformedErrorString("JSON Object-EOS",
							     jsonstring));
      } else if(it.current() == '}') {
	// end of object
	array.add(curElement);
	curElement = "";
	String dummy[] = new String[0];
	return array.toArray(dummy);
      } else if(readingName && it.current() != ':') {
	// reading name
	curElement += it.current();
	it.next();
      } else if(readingName && it.current() == ':') {
	// end name
	it.next();
	array.add(curElement);
	curElement = "";
	readingName = false;
      } else if(it.current() != ',') {
	// reading value
	curElement += it.current();
	it.next();
      } else {
	// end name-value pair
	it.next();
	array.add(curElement);
	curElement = "";
	readingName = true;
      }
    }
  }

  /**
   * Generic malformed JSON error text orginating while parsing callee
   * and parsing the string str
   **/
  public static String malformedErrorString(String callee, String str) {
    return "The following string is malformed JSON and was encountered while "
      + "attempting to read " + callee + ".\n\"" + str + "\"\n---";
  }

}
